<template>
  <div>
    <div class="floatBtn" :class="[{ moveBtn: longClick }, `${btnType}Btn`]" @touchstart="touchstart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)">
      <span>悬浮按钮</span>
    </div>
  </div>
</template>
<script>
export default {
  name: "FloatBtn",
  data() {
    return {
      timeOutEvent: 0,
      longClick: 0,
      // 手指原始位置
      oldMousePos: {},
      // 元素原始位置
      oldNodePos: {},
      btnType: "right",
    };
  },
  touchstart(ev) {
    // 定时器控制长按时间，超过500毫秒开始进行拖拽
    this.timeOutEvent = setTimeout(() => {
      this.longClick = 1;
    }, 500);
    const selectDom = ev.currentTarget;
    const { pageX, pageY } = ev.touches[0]; // 手指位置
    const { offsetLeft, offsetTop } = selectDom; // 元素位置
    // 手指原始位置
    this.oldMousePos = {
      x: pageX,
      y: pageY,
    };
    // 元素原始位置
    this.oldNodePos = {
      x: offsetLeft,
      y: offsetTop,
    };
    selectDom.style.left = `${offsetLeft}px`;
    selectDom.style.top = `${offsetTop}px`;
  },
  touchMove(ev) {
    // 未达到500毫秒就移动则不触发长按，清空定时器
    clearTimeout(this.timeOutEvent);
    if (this.longClick === 1) {
      const selectDom = ev.currentTarget;
      // x轴偏移量
      const lefts = this.oldMousePos.x - this.oldNodePos.x;
      // y轴偏移量
      const tops = this.oldMousePos.y - this.oldNodePos.y;
      const { pageX, pageY } = ev.touches[0]; // 手指位置
      selectDom.style.left = `${pageX - lefts}px`;
      selectDom.style.top = `${pageY - tops}px`;
    }
  },
  touchEnd(ev) {
    // 清空定时器
    clearTimeout(this.timeOutEvent);
    if (this.longClick === 1) {
      this.longClick = 0;
      const selectDom = ev.currentTarget;
      const { clientWidth, clientHeight } = document.body;
      const { offsetLeft, offsetTop } = selectDom;
      selectDom.style.left = offsetLeft + 50 > clientWidth / 2 ? "calc(100% - 100px)" : 0;
      if (offsetTop < 90) {
        selectDom.style.top = "90px";
      } else if (offsetTop + 36 > clientHeight) {
        selectDom.style.top = `${clientHeight - 36}px`;
      }
      this.btnType = offsetLeft + 50 > clientWidth / 2 ? "right" : "left";
    }
  },
};
</script>
<style lang="scss" scoped>
@mixin notSelect{
    -moz-user-select:none; /*火狐*/
    -webkit-user-select:none; /*webkit浏览器*/
    -ms-user-select:none; /*IE10*/
    -khtml-user-select:none; /*早期浏览器*/
    user-select:none;
  }
  @mixin not-touch {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }
  .floatBtn {
    @include notSelect;
    @include not-touch();
    position: fixed;
    z-index: 1;
    overflow: hidden;
    width: 100px;
    left: calc(100% - 100px);
    top: calc(100% - 100px);
    color: #E0933A;
    background: #FCEBD0;
    font-size: 14px;
    height: 36px;
    line-height: 36px;
    text-align: center;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 10px;
    &.rightBtn {
      border-radius: 20px 0 0 20px;
    }
    &.leftBtn {
      border-radius: 0 20px 20px 0;
    }
    &.moveBtn {
      border-radius: 20px;
    }
  }
</style>
